package setup

import (
	"blog_server/global"
	"blog_server/internal/model/entity"
	"blog_server/pkg/setting"
	"fmt"
	"github.com/aliyun/aliyun-oss-go-sdk/oss"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	rotatelogs "github.com/lestrrat-go/file-rotatelogs"
	"github.com/sirupsen/logrus"
	"log"
	"os"
	"time"
)

func init() {
	err := initGlobalSetting()
	if err != nil {
		log.Fatalf("setup.initGlobalSetting err: %v", err)
	}
	err = initGlobalLogger()
	if err != nil {
		log.Fatalf("setup.initGlobalLogger err: %v", err)
	}
	err = initGlobalDBEngine()
	if err != nil {
		log.Fatalf("setup.initGlobalDBEngine err: %v", err)
	}
	err = initGlobalOSSBucket()
	if err != nil {
		log.Fatalf("setup.initGlobalOSSBucket err: %v", err)
	}
}

/*
	读取配置
	初始化全局配置变量
*/
func initGlobalSetting() error {
	s, err := setting.NewSetting("configs/")
	if err != nil {
		return err
	}
	err = s.ReadSection("Server", &global.ServerSetting)
	if err != nil {
		return err
	}
	err = s.ReadSection("Database", &global.DatabaseSetting)
	if err != nil {
		return err
	}
	err = s.ReadSection("JWT", &global.JWTSetting)
	if err != nil {
		return err
	}
	err = s.ReadSection("App", &global.AppSetting)
	if err != nil {
		return err
	}
	err = s.ReadSection("OSS", &global.OssSetting)
	if err != nil {
		return err
	}

	global.AppSetting.DefaultContextTimeout *= time.Second
	global.JWTSetting.Expire *= time.Second
	global.ServerSetting.ReadTimeout *= time.Second
	global.ServerSetting.WriteTimeout *= time.Second

	return nil
}

/*
	初始化全局logger
*/
func initGlobalLogger() error {
	logger := logrus.New()
	logger.SetFormatter(&logrus.JSONFormatter{TimestampFormat: "2006-01-02 15:04:05"})
	path := global.AppSetting.LogSavePath

	if global.ServerSetting.RunMode == "release" {
		err := os.MkdirAll(global.AppSetting.LogSavePath, 0666)
		if err != nil {
			return err
		}
		writer, _ := rotatelogs.New(path+".%Y%m%d%H%M",
			rotatelogs.WithLinkName(path),
			rotatelogs.WithMaxAge(time.Duration(168)*time.Hour),
			rotatelogs.WithRotationTime(time.Duration(720)*time.Hour))
		logger.SetOutput(writer)
		logger.SetFormatter(&logrus.JSONFormatter{})
	}

	logger.SetReportCaller(true)
	global.Logger = logger
	return nil
}

/*
	初始化全局DBEngine
*/
func initGlobalDBEngine() error {
	var err error
	global.DBEngine, err = NewDBEngine(global.DatabaseSetting)
	return err
}

/*
	初始化全局OSSBucket
*/
func initGlobalOSSBucket() error {
	var err error
	global.OSSBucket, err = NewOSSBucket(global.OssSetting)
	return err
}

func NewOSSBucket(ossSetting *setting.OssSettingS) (*oss.Bucket, error) {
	client, err := oss.New(ossSetting.Endpoint, ossSetting.AccessKeyID, ossSetting.AccessKeySecret)
	if err != nil {
		return nil, err
	}
	return client.Bucket(ossSetting.BucketName)
}

func NewDBEngine(databaseSetting *setting.DatabaseSettingS) (*gorm.DB, error) {
	db, err := gorm.Open(databaseSetting.DBType, fmt.Sprintf("%s:%s@tcp(%s)/%s?charset=%s&parseTime=%t&loc=Local",
		databaseSetting.UserName,
		databaseSetting.Password,
		databaseSetting.Host,
		databaseSetting.DBName,
		databaseSetting.Charset,
		databaseSetting.ParseTime,
	))
	if err != nil {
		return nil, err
	}
	db.SingularTable(true)

	db.AutoMigrate(&entity.Article{})
	db.AutoMigrate(&entity.Tag{})
	db.AutoMigrate(&entity.TagArticle{})
	db.AutoMigrate(&entity.Category{})
	db.AutoMigrate(&entity.FriendLink{})
	db.AutoMigrate(&entity.Author{})
	db.AutoMigrate(&entity.User{})

	if global.ServerSetting.RunMode == "debug" {
		db.LogMode(true)
	}
	db.DB().SetMaxIdleConns(databaseSetting.MaxIdleConns) //设置最大空闲连接数量
	db.DB().SetMaxOpenConns(databaseSetting.MaxOpenConns) //设置最大连接数量
	return db, nil
}
